<?php

namespace MUD;

class Map{
    private $rooms;
    public $room;
    private $last_id;
    
    public function __construct(){
        $this->rooms = array();
        $this->room=NULL;
        $this->loadRooms();
    }
    
    public function walk($direction){
        if(strlen($direction) == 1){
            switch($direction){
                case 'n' : $direction = 'north'; break;
                case 's' : $direction = 'south'; break;
                case 'e' : $direction = 'east';  break;
                case 'w' : $direction = 'west';  break;
                case 'u' : $direction = 'up';    break;
                case 'd' : $direction = 'down';  break;
                case 'b' : $direction = 'back';  break;
            }
        }
        $direction = 'exit_'.$direction;
        if(isset($this->room->{$direction}) && $this->room->{$direction}['id'] > 0){
            $new_room = $this->rooms[$this->room->{$direction}['id']];
            
            $this->last_id = $this->room->id;
            $this->room = $new_room;
            
            $this->printRoom();
            
            //announce our arrival to everyone
            $getClientsInRoom = R::current()->dbo->select('pid', 'clientracker', "location='".$this->room->id."' AND client_id != '".R::current()->client->user_id."'");
            $numClientsInRoom = R::current()->dbo->rows;
            $clientsInRoom = R::current()->dbo->result;
            if($numClientsInRoom > 0){
                for($i=0;$i<$numClientsInRoom;$i++){
                    R::current()->client->whisper(R::current()->client->username." has entered the room.", $clientsInRoom[$i]['pid'], true, false);
                }
            }
            
            //update location in DB
            $data = array(
              'location' => $this->room->id  
            );
            R::current()->dbo->update("clientracker", $data, "client_id='".R::current()->client->user_id."'", 1);
        }else{
            R::current()->client->send("You can't go that way.", "\n", true);
        }
    }
    
    public function printRoom(){
        $output = $this->room->title;
        if(R::current()->client->prefs['show_room_descriptions'] == 1){
            $output .= "\n" . $this->room->description;
        }
        
        //check for items in the room
        if(($ic = count($this->room->items)) > 0){
            for($i=0;$i<$ic;$i++){
                $output .= $this->room->items[$i]->ground."\n";
            }
            $output = rtrim($output);
        }
        
        //check for other players in the room
        $getPlayers = R::current()->dbo->query("SELECT client_id, users.username FROM clientracker JOIN users ON users.id=clientracker.client_id WHERE clientracker.client_id != '".R::current()->client->user_id."' AND location='".$this->room->id."'", true);
        if($getPlayers){
            $rows=R::current()->dbo->rows;
            $result=R::current()->dbo->result;
            if($rows >= 1){
                for($i=0;$i<$rows;$i++){
                    $output .= "\n" . $result[$i]['username']." is standing near by.";
                }
            }
        }
        
        R::current()->client->send($output, "\n", true);
    }
    
    public function getLastRoom(){
        if(isset($this->last_id)){
            return $this->rooms[$this->last_id];
        }else{
            return false;
        }
    }
    
    /*d
     * This should probably only be used for setting the starting room after login.
     */
    public function setCurrentRoom($id){
        if(array_key_exists($id, $this->rooms)){
            if(is_object($this->room)){
                $this->last_id = $this->room->id;
            }
            $this->room = $this->rooms[$id];
        }
    }
    
    protected function loadRooms(){
        $this->rooms=array();
        $this->fd = simplexml_load_file(__ROOT__.DS.'res'.DS.'map.xml');
        foreach($this->fd->room as $room){
            $id = (string) $room['id'];
            $title = (string) $room->title;
            $description = (string) $room->description;
            $key=NULL;
            if(isset($room->key)){
                //room requires a key to get entry
                $open=false;
                $key=$room->key;
            }
            $code=NULL;
            if(isset($room->code)){
                //room requires a code to get entry
                $open=false;
                $code=$room->code;
            }
            
            $otherAttribs=array('key' => $key, 'code' => $code);
            
            $exits=array(
                'north' => array(
                    'id' => (string) $room->exits->north['id'],
                    'title' => (string) $room->exits->north
                ),
                'south' => array(
                    'id' => (string) $room->exits->south['id'],
                    'title' => (string) $room->exits->south
                ),
                'east' => array(
                    'id' => (string) $room->exits->east['id'],
                    'title' => (string) $room->exits->east
                ),
                'west' => array(
                    'id' => (string) $room->exits->west['id'],
                    'title' =>  (string) $room->exits->west
                ),
                'up' => array(
                    'id' => (string) $room->exits->up['id'],
                    'title' => (string) $room->exits->up
                ),
                'down' => array(
                    'id' => (string) $room->exits->down['id'],
                    'title' => (string) $room->exits->down
                )
            );
            //check if this room has it's own function to be loaded
            if(isset($room['hasfunction'])){
                //load custom room function
                $func=str_replace(' ', '', ucwords($title)).'Room';
                $this->rooms[$id]=new $func($id, $title, $description, $exits, $otherAttribs);
            }else{
                //load default room function
                $this->rooms[$id]=new Room($id, $title, $description, $exits, $otherAttribs);
            }
        }
    }
    
    public function addItemToRoom($room_id, $item_id){
        $this->rooms[$room_id]->addItem($item_id);
        if($room_id == $this->room->id){
            //add to current room
            $this->room->addItem($item_id);
        }
    }
}